diff options
Diffstat (limited to 'app/[lng]')
| -rw-r--r-- | app/[lng]/partners/(partners)/dolce-upload/dolce-upload-page.tsx | 110 | ||||
| -rw-r--r-- | app/[lng]/partners/(partners)/dolce-upload/page.tsx | 15 |
2 files changed, 71 insertions, 54 deletions
diff --git a/app/[lng]/partners/(partners)/dolce-upload/dolce-upload-page.tsx b/app/[lng]/partners/(partners)/dolce-upload/dolce-upload-page.tsx index db8d528b..43800838 100644 --- a/app/[lng]/partners/(partners)/dolce-upload/dolce-upload-page.tsx +++ b/app/[lng]/partners/(partners)/dolce-upload/dolce-upload-page.tsx @@ -1,6 +1,7 @@ "use client"; import { useState, useEffect, useCallback, useMemo } from "react"; +import { useParams } from "next/navigation"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Alert, AlertDescription } from "@/components/ui/alert"; import { Skeleton } from "@/components/ui/skeleton"; @@ -16,6 +17,7 @@ import { } from "@/components/ui/select"; import { InfoIcon, RefreshCw, Search, Upload } from "lucide-react"; import { toast } from "sonner"; +import { useTranslation } from "@/i18n/client"; import { UnifiedDwgReceiptItem, fetchDwgReceiptList, @@ -33,6 +35,10 @@ interface DolceUploadPageProps { } export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) { + const params = useParams(); + const lng = params?.lng as string; + const { t } = useTranslation(lng, "dolce"); + // URL에서 초기 프로젝트 코드 const initialProjNo = (searchParams.projNo as string) || ""; @@ -78,7 +84,7 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) fetchVendorProjects(), ]); - setVendorInfo(vendorInfoData); + setVendorInfo(vendorInfoData as typeof vendorInfo); setProjects(projectsData); // 초기 프로젝트가 있으면 도면 로드 @@ -92,12 +98,12 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) } } catch (err) { console.error("초기 데이터 로드 실패:", err); - setError(err instanceof Error ? err.message : "데이터 로드 실패"); - toast.error("데이터 로드 실패"); + setError(err instanceof Error ? err.message : t("page.initialLoadError")); + toast.error(t("page.initialLoadError")); } finally { setIsLoading(false); } - }, [initialProjNo]); + }, [initialProjNo, t]); // 도면 목록 조회 const loadDrawings = useCallback(async () => { @@ -114,21 +120,28 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) }); setDrawings(drawingsData); - toast.success("도면 목록을 갱신했습니다"); + toast.success(t("page.drawingLoadSuccess")); } catch (err) { console.error("도면 로드 실패:", err); - setError(err instanceof Error ? err.message : "도면 로드 실패"); - toast.error("도면 로드 실패"); + setError(err instanceof Error ? err.message : t("page.drawingLoadError")); + toast.error(t("page.drawingLoadError")); } finally { setIsRefreshing(false); } - }, [projNo, vendorInfo]); + }, [projNo, vendorInfo, t]); // 초기 데이터 로드 useEffect(() => { loadInitialData(); }, [loadInitialData]); + // 프로젝트 변경 시 자동 검색 + useEffect(() => { + if (projNo && vendorInfo) { + loadDrawings(); + } + }, [projNo, vendorInfo, loadDrawings]); + // 도면 클릭 핸들러 const handleDrawingClick = (drawing: UnifiedDwgReceiptItem) => { setSelectedDrawing(drawing); @@ -227,7 +240,7 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) <Alert> <InfoIcon className="h-4 w-4" /> <AlertDescription> - 프로젝트를 선택하여 도면 목록을 조회하세요. + {t("page.selectProject")} </AlertDescription> </Alert> )} @@ -235,16 +248,16 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) {/* 필터 카드 */} <Card> <CardHeader> - <CardTitle>검색 필터</CardTitle> + <CardTitle>{t("filter.title")}</CardTitle> </CardHeader> <CardContent> <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"> {/* 프로젝트 선택 */} <div className="space-y-2"> - <Label>프로젝트</Label> + <Label>{t("filter.project")}</Label> <Select value={projNo} onValueChange={setProjNo}> <SelectTrigger> - <SelectValue placeholder="프로젝트를 선택하세요" /> + <SelectValue placeholder={t("filter.projectPlaceholder")} /> </SelectTrigger> <SelectContent> {projects.map((project) => ( @@ -258,77 +271,69 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) {/* 도면번호 검색 */} <div className="space-y-2"> - <Label>도면번호 (Drawing No)</Label> + <Label>{t("filter.drawingNo")}</Label> <Input value={drawingNo} onChange={(e) => setDrawingNo(e.target.value)} - placeholder="도면번호 입력" + placeholder={t("filter.drawingNoPlaceholder")} /> </div> {/* 도면명 검색 */} <div className="space-y-2"> - <Label>도면명 (Drawing Name)</Label> + <Label>{t("filter.drawingName")}</Label> <Input value={drawingName} onChange={(e) => setDrawingName(e.target.value)} - placeholder="도면명 입력" + placeholder={t("filter.drawingNamePlaceholder")} /> </div> {/* 설계공종 검색 */} <div className="space-y-2"> - <Label>설계공종 (Discipline)</Label> + <Label>{t("filter.discipline")}</Label> <Input value={discipline} onChange={(e) => setDiscipline(e.target.value)} - placeholder="설계공종 입력" + placeholder={t("filter.disciplinePlaceholder")} /> </div> {/* 담당자명 검색 (클라이언트 필터) */} <div className="space-y-2"> - <Label>담당자명 (Manager)</Label> + <Label>{t("filter.manager")}</Label> <Input value={manager} onChange={(e) => setManager(e.target.value)} - placeholder="담당자명 입력" + placeholder={t("filter.managerPlaceholder")} /> </div> {/* B4(GTT) 전용: Document Type 필터 */} {vendorInfo?.drawingKind === "B4" && ( <div className="space-y-2"> - <Label>Document Type</Label> + <Label>{t("filter.documentType")}</Label> <Select value={documentType} onValueChange={(value) => setDocumentType(value as DocumentType)}> <SelectTrigger> <SelectValue /> </SelectTrigger> <SelectContent> - <SelectItem value="ALL">ALL (전체)</SelectItem> - <SelectItem value="GTT_DELIVERABLES">GTT Deliverables (도면입수)</SelectItem> - <SelectItem value="SHI_INPUT">SHI Input Document (도면제출)</SelectItem> + <SelectItem value="ALL">{t("filter.documentTypeAll")}</SelectItem> + <SelectItem value="GTT_DELIVERABLES">{t("filter.documentTypeGttDeliverables")}</SelectItem> + <SelectItem value="SHI_INPUT">{t("filter.documentTypeSHIInput")}</SelectItem> </SelectContent> </Select> </div> )} </div> - <div className="flex gap-2 mt-4"> + <div className="flex gap-2 mt-4 justify-end"> <Button onClick={handleSearch} disabled={!projNo || isRefreshing} - className="flex-1" > <Search className="h-4 w-4 mr-2" /> - 검색 - </Button> - <Button - variant="outline" - onClick={handleRefresh} - disabled={!projNo || isRefreshing} - > - <RefreshCw className={`h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`} /> + {t("filter.searchButton")} </Button> {/* B4 벤더인 경우에만 일괄 업로드 버튼 표시 */} {vendorInfo?.drawingKind === "B4" && ( @@ -338,9 +343,16 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) disabled={!projNo || isRefreshing} > <Upload className="h-4 w-4 mr-2" /> - 일괄 업로드 + {t("filter.bulkUploadButton")} </Button> )} + <Button + variant="outline" + onClick={handleRefresh} + disabled={!projNo || isRefreshing} + > + <RefreshCw className={`h-4 w-4 ${isRefreshing ? "animate-spin" : ""}`} /> + </Button> </div> </CardContent> </Card> @@ -350,24 +362,20 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) <Card> <CardHeader> <CardTitle> - 도면 리스트 - {filteredDrawings.length > 0 && ` (${filteredDrawings.length}건)`} + {t("drawingList.title")} + {filteredDrawings.length > 0 && ` ${t("drawingList.count", { count: filteredDrawings.length })}`} </CardTitle> </CardHeader> <CardContent className="overflow-x-auto"> - {vendorInfo.drawingKind === "B4" ? ( - <DrawingListTable - columns={createGttDrawingListColumns({ documentType })} - data={filteredDrawings} - onRowClick={handleDrawingClick} - /> - ) : ( - <DrawingListTable - columns={drawingListColumns} - data={filteredDrawings} - onRowClick={handleDrawingClick} - /> - )} + <DrawingListTable + columns={ + vendorInfo.drawingKind === "B4" + ? (createGttDrawingListColumns({ documentType, lng, t }) as unknown as typeof drawingListColumns) + : (drawingListColumns(lng, t) as unknown as typeof drawingListColumns) + } + data={filteredDrawings} + onRowClick={handleDrawingClick} + /> </CardContent> </Card> )} @@ -383,6 +391,7 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) userName={vendorInfo.userName} userEmail={vendorInfo.email} drawingKind={vendorInfo.drawingKind} + lng={lng} /> )} @@ -397,6 +406,7 @@ export default function DolceUploadPage({ searchParams }: DolceUploadPageProps) userEmail={vendorInfo.email} vendorCode={vendorInfo.vendorCode} onUploadComplete={handleBulkUploadComplete} + lng={lng} /> )} </div> diff --git a/app/[lng]/partners/(partners)/dolce-upload/page.tsx b/app/[lng]/partners/(partners)/dolce-upload/page.tsx index 97582819..4d7b1a74 100644 --- a/app/[lng]/partners/(partners)/dolce-upload/page.tsx +++ b/app/[lng]/partners/(partners)/dolce-upload/page.tsx @@ -31,11 +31,14 @@ function DolceUploadSkeleton() { } export default async function DolceUploadPageWrapper({ + params, searchParams, }: { + params: Promise<{ lng: string }>; searchParams: Promise<{ [key: string]: string | string[] | undefined }>; }) { - const params = await searchParams; + const { lng } = await params; + const resolvedParams = await searchParams; return ( <Shell> @@ -43,17 +46,21 @@ export default async function DolceUploadPageWrapper({ <div className="flex items-center justify-between"> <div> <h2 className="text-2xl font-bold tracking-tight"> - DOLCE 문서 업로드 + {lng === "ko" + ? "DOLCE 도면 업로드" + : "DOLCE Drawing Upload"} </h2> <p className="text-muted-foreground"> - 설계문서를 조회하고 업로드할 수 있습니다 + {lng === "ko" + ? "설계문서를 조회하고 업로드할 수 있습니다" + : "View and upload design documents"} </p> </div> </div> {/* 메인 컨텐츠 */} <Suspense fallback={<DolceUploadSkeleton />}> - <DolceUploadPage searchParams={params} /> + <DolceUploadPage searchParams={resolvedParams} /> </Suspense> </Shell> ); |
